<?php

/**
 *
 */
abstract class App_Model_Mapper_Abstract {

    /**
     *
     * @var array
     */
    protected $_data;

    /**
     *
     * @var array
     */
    protected $_methodsValidators = array();

    /**
     *
     * @var bool
     */
    protected $_breakOnFailure = true;

    /**
     *
     * @var App_Message
     */
    protected $_message;

    /**
     *
     * @var Zend_Config
     */
    protected $_config;

    /**
     *
     * @var Zend_Session_Namespace
     */
    protected $_session;

    /**
     * 
     * @access public
     * @return void
     */
    public function __construct() {
        $this->_message = new App_Message();
        $this->_config = Zend_Registry::get('config');
        $this->_session = new Zend_Session_Namespace($this->_config->geral->appid);
    }

    /**
     * 
     * @access 	public
     * @param 	array $data
     * @return 	void
     */
    public function setData(array $data) {
        $this->_data = $data;
        return $this;
    }

    /**
     * 
     * @access 	public
     * @return 	mixed
     */
    public function getData() {
        return $this->_data;
    }

    /**
     * 
     * @access 	public
     * @param 	array $validators
     * @param 	boolean $breakOnFailure
     * @return 	void
     */
    public function setValidators(array $validators, $breakOnFailure = true) {
        $this->_methodsValidators = $validators;

        $this->setBreakOnFailure($breakOnFailure);
    }

    /**
     * 
     * @access 	public
     * @param 	boolean $breakOnFailure
     * @return 	boolean
     */
    public function setBreakOnFailure($breakOnFailure) {
        $this->_breakOnFailure = (bool) $breakOnFailure;
    }

    /**
     * 
     * @access 	public
     * @return 	boolean
     * @throws 	Exception
     */
    public function isValid() {
        $check = true;

        foreach ($this->_methodsValidators as $method) {

            if (method_exists($this, $method)) {

                if (!call_user_func(array($this, $method))) {
                    if ($this->_breakOnFailure)
                        return false;
                    else
                        $check = false;
                }
            } else {

                throw new Exception('Method ' . $method . ' is not valid in the context of validation.');
            }
        }

        return $check;
    }

    /**
     * 
     * @access 	public
     * @return 	App_Message
     */
    public function getMessage() {
        return $this->_message;
    }

    /**
     * 
     * @access 	protected
     * @param 	App_Model_DbTable_Abstract $dbTable
     * @return 	int
     */
    protected function _simpleSave(App_Model_DbTable_Abstract $dbTable, $message = true) {
        $primary = $dbTable->getPrimaryKey();

        $this->_data = $this->_emptyToNull($this->_data);

        if (empty($this->_data[$primary])) {

            $row = $dbTable->createRow();
            $row->setFromArray($this->_data);

            $result = $row->save();
        } else {

            $where = array($primary . ' = ?' => $this->_data[$primary]);

            $data = $dbTable->cleanData($this->_data);

            $result = (false !== $dbTable->update($data, $where)) ? $this->_data[$primary] : false;
        }

        if ($result)
            $this->_message->addMessage($this->_config->messages->success, App_Message::SUCCESS);
        else
            $this->_message->addMessage($this->_config->messages->error, App_Message::ERROR);

        return $result;
    }

    /**
     *
     * @param array $data
     * @return array 
     */
    protected function _emptyToNull($data) {
        foreach ($data as $key => $value)
            if ($value === '')
                $data[$key] = null;

        return $data;
    }

}